home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
rdir.zip
/
RDIR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-14
|
23KB
|
752 lines
/*
* RDIR.C : A resident directory lister. This shows how to access DOS from
* within a Turbo C resident program. To completely recompile this
* code you must have MASM or a compatible compiler. Unfortunately
* everything but trapping the BIOS Disk service software
* interrrupt could be done in Turbo C. See code commentary.
*
* To activate the program once loaded, press Ctrl and Alt together.
* I know this combination gets in the way of SideKick, but I don't use
* sidekick <grin> and this is meant as a tutorial anyway. If you would
* like to change this combination see Hot_Combo in the source code.
* Next, enter the pattern for the directory search followed either by
* Enter or Ctrl-Enter. Enter will not include directories. Ctrl-Enter
* will include directories. Directories are displayed in white where
* other files are displayed in cyan. Hidden and system files are included.
* The page up and page down keys may be used to see other parts of large
* directory listings.
*
* Written by Dean D. McCrory
* For Turbo C 1.00
* May 14, 1987
*
* Compile with:
* masm -mx bioshand.asm;
* masm -mx intvid.asm;
* tcc -N- rdir.c bioshand.obj intvid.obj
*
* The -N- switch turns stack checking off which is a definite requirement
* for writing ISRs. Have fun <grin>.
*/
#include <dos.h>
#include <dir.h>
#include "intvid.h"
/* function prototypes */
int main (void);
unsigned prgsize (void);
void exit (int);
char far * getdosbusy (void);
void interrupt timer_handler (void);
void do_click (void);
void interrupt special_handler (void);
void interrupt keyboard_handler (void);
extern void interrupt biosdisk_handler (void);
void interrupt break_handler (void);
void list_directory (void);
void set_screen (void);
void get_pattern (void);
void display_entries (void);
void find_entry (void);
void sc_putsa (int, int, char *, int);
void sc_putca (int, int, char, int);
void sc_repvca (int, int, char, int, int);
void sc_rephca (int, int, char, int, int);
void sc_savbox (int, int, int, int, char *);
void sc_resbox (int, int, int, int, char *);
void sc_rptpos (int *, int *);
void sc_setpos (int, int);
char far * sc_cca (int, int);
int getkey ();
/* Define the structure which will be attached to interrupt d0 so we can
determine if rdir is already loaded */
typedef struct s_rdir_cfg
{
char iret; /* iret first, just in case */
long * signature; /* signature string */
} t_rdir_cfg;
/* Suppress some library functions to conserve space */
_setargv () {}
_setenvp () {}
/* defines for various things, in alot of these things we are looking right
into the BIOS data area. See Peter Norton's Guide to the IBM-PC or
your Tech. Ref. for an expanation of these data items. */
#define Screen_Ram ((char far *) 0xb8000000L) + (*(int far *) 0x0000044eL)
#define Display_Page (*(char far *) 0x00000462L)
#define Iret 0xcf /* for iret in int d1 just in case */
#define Intr 0xd1 /* interrupt for install checking */
#define Timer 0x1c /* timer interrupt number */
#define Keyboard 0x09 /* keyboard hardware interrupt */
#define Special 0x28 /* special interrupt 28h */
#define Critical 0x24 /* hardware critical interrupt 24h */
#define Break 0x1b /* bios ctrl-break interrupt */
#define BiosDisk 0x13 /* bios diskette services */
#define NotOk 1 /* already installed return code */
#define Ok 0 /* success return code */
#define Shift_Bits ((char far *) 0x00000417L)
#define Hot_Combo ((*Shift_Bits & 12) == 12) /* Our hot key combo */
#define Box_Row 4 /* row of box */
#define Box_Col 4 /* column of box */
#define Box_Hgt 17 /* height of box */
#define Box_Wdth 70 /* widht of box */
#define Box_Attr 0x4f /* attribute of box border */
#define Box_Incr 14 /* number of columns between start of filenames */
#define Pat_Size 64 /* size of a pattern string */
#define Norm_Attr 3 /* attribute of normal files */
#define Dir_Attr 15 /* attribute of directories */
#define Name_Size 12 /* size of each file name when displayed */
#define Per_Screen 5 * (Box_Hgt - 2) /* number of dir entries in box */
/* Defines for key values as returned by getkey () */
#define Page_Up_Key 329
#define Page_Dn_Key 337
#define Escape_Key 27
#define BackSpace_Key 8
#define Enter_Key 13
#define Ctrl_Enter_Key 10
char box_buf[Box_Hgt * Box_Wdth * 2]; /* buffer for saving screen */
int old_row, old_col; /* row and col of cursor */
int current_entry; /* last dir entry read */
int entries_to_skip; /* first entry on display */
char pattern[Pat_Size]; /* pattern for dir searches */
int attrib; /* attrib for dir searches */
struct ffblk ffblk; /* file-find block */
int key, status; /* last key, and last ff status */
t_vidreg regs; /* global regs structure */
char far * ptr; /* general purpose far pointer */
char far * buf_pos; /* another of the same */
int next_line; /* used by screen stuff */
/* Our configuration structure... nothing in it but the signature */
t_rdir_cfg rdir_cfg =
{
Iret, (long *) "rdir"
};
void interrupt (* old_timer) (); /* previous timer interrupt vector */
void interrupt (* old_keyboard) (); /* previous keyboard int vector */
void interrupt (* old_special) (); /* previous int 28h vector */
void interrupt (* old_biosdisk) (); /* previous bios disk svc vector */
void interrupt (* old_critical) (); /* previous int 24h vector */
void interrupt (* old_break) (); /* pervious int 1bh vector */
char far * old_dta; /* disk transfer address save area */
static char far * dosbusy_fl; /* dos maintains this */
char biosbusy_fl = 0; /* I maintain this */
static int request_fl = 0; /* 0 - no request
1 - request made
2 - request being serviced
*/
int main ()
{
t_rdir_cfg far * cfg_ptr;
/* get old configuration information (mayebe) */
cfg_ptr = (t_rdir_cfg far *) getvect (Intr);
/* check to see if we are already installed */
if (*cfg_ptr->signature != *rdir_cfg.signature)
{
/* we were not installed so install ourselves */
old_timer = getvect (Timer);
old_keyboard = getvect (Keyboard);
old_special = getvect (Special);
old_biosdisk = getvect (BiosDisk);
setvect (Timer, timer_handler);
setvect (Special, special_handler);
setvect (BiosDisk, biosdisk_handler);
setvect (Keyboard, keyboard_handler);
setvect (Intr, (void interrupt (*) ()) &rdir_cfg);
dosbusy_fl = getdosbusy ();
keep (Ok, prgsize ());
}
return (NotOk);
}
/* prgsize ()
*
* Calculates the program size by looking at __brklvl which is set to
* the end of initialized and uninitialized data whithin the data segment
* at program startup. __brklvl is then changed as memory space is
* malloc'd. __brklvl is decremented as malloc'd areas are free'd.
*
* ** This function should work in Tiny, Small, and Meduim models **
*/
unsigned prgsize ()
{
extern unsigned __brklvl; /* current top of heap == sbrk (0) */
extern unsigned _psp; /* lowest segment address occupied */
return (_DS + (__brklvl + 15) / 16 - _psp);
}
/* exit ()
*
* Rewrite exit for memory conservation. This exit () does not close files
* or flush buffers, which is fine in this case because we have no open
* files or buffers which need to be flushed.
*
*/
void exit (status)
int status;
{
_exit (status);
}
/* getdosbusy ()
*
* Gets the Dos busy flag th